react hooks 使用实例
通过reducer来处理dispatch出来的各种action
reducer.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| export const dataFetchReducer = (state: any, action: {[type: string]: any}) => { switch(action.type) { case 'FETCH_INIT': return { ...state, isLoading: true, isError: false } case 'FETCH_SUCCESS': return { ...state, isLoading: false, isError: false data: action.payload } case 'FETCH_ERROR': return { ...state, isLoading: false, isError: true, msg: action.payload } default: throw new Error(`Unsupport action type:${action.type}`); } }
|
自定义一个获取数据的React Hooks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| interface RequestConfig extends AxiosRequestConfig{ url: string }
exports const useDataApi = (initData: Array<any> | any, initRequestConfig: RequestConfig) { if (!initRequstConfog.method) { initRequstConfog.method = "get"; } const [requestConfig, setRequestConfig] = useState(initRequestConfig); const [state, dispatch] = useReducer(dataFetchReducer, { data: initData, isLoading: false, isError: false });
useEffect(() => { const fetchData = async () => { try { dispatch({ type: 'FETCH_INIT' }); if (!requestConfig.url) { dispatch({ type: 'FETCH_SUCCESS', payload: [] }); } else { const response = await axios(requestConfig).catch(e => return e.response); if (response.data) { const data = response.data; const { success, result, message } = data; if (!success) { dispatch({ type: 'FETCH_ERROR', payload: message }); } else { dispatch({ type: 'FETCH_SUCCESS', payload: result }); } } else { dispatch({ type: 'FETCH_ERROR', payload: '加载数据失败' }); } } } catch(error) { dispatch({ type: 'FETCH_ERROR' msg: '加载数据失败' }); } } }, [requestConfig]); return [state, setRequestConfig] }
|
使用自定义的Hooks来加载数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const [{isLoading, isError, msg, data}, setRequestConfig] = useDataApi([], {url: apiPath}); if (isError) { message.error(msg); return ( <div> <div className="toolbar"> <Link to={window.location.pathname+ '/detail'} > <Button type="primary" icon="plus" > 添加 </Button> </Link> </div> <CustomModal /> <Table columns={columns} dataSource={data} loading={isLoading} rowKey={'id'} /> </div> ) }
|